package cc.telecomdigital.tdstock.trading.Services;

import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;

import cc.telecomdigital.tdstock.R;
import cc.telecomdigital.tdstock.Framework.UniqueItem.DeviceInfo;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.Services.SoapTransport;
import cc.telecomdigital.tdstock.trading.Common.Trade_AppConstant;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

/** Logout use similar command as Login, but we would neglect the result.  Actually we do not care about the result **/
public class TradeLogout
{	
	private final String	LOG_TAG	= "TradeLogout";

	// Call back interface
	public interface ITradeLogoutResponse
	{		
		/** if iSuccessfulSend == false, it means the there is a communication error
		    do not consider the iReponse as valid response **/
		void ResponseFunc(boolean iSuccessfulSend );
	}

	private final boolean debugMode = false;
	private SoapObject	  soapRequest;
	private Context	  callerContext;
	private boolean	  demoData	= false;
	private Handler	  messageHandler;

	/** Requesting for a Login
	 * @param iContext - Owner
	 * @param iName - Server required userName
	 * @param iPassword - Server required password
	**/		
	public TradeLogout(Context iCallerContext, String iName)
	{
		callerContext = iCallerContext;
		soapRequest = new SoapObject(TradeAppInfo.NAMESPACE, "Login");
		
		soapRequest.addProperty("DeviceID",
				TradeAppInfo.GetDeviceID(iCallerContext));
		soapRequest.addProperty("UIN", TradeAppInfo.GetUIN());
		soapRequest.addProperty("ProtocolVer",
				TradeAppInfo.GetProtocolVersion());
		soapRequest.addProperty("ProgramVer",
				TradeAppInfo.GetProgramVersion());
		soapRequest.addProperty("OSVer", TradeAppInfo.GetOSVersion());
		soapRequest.addProperty("DeviceVer", TradeAppInfo.GetDeviceVer());
		soapRequest.addProperty("BrokerID", TradeAppInfo.BrokerID);
		soapRequest.addProperty("ClientID", iName);
		soapRequest.addProperty("Language", DeviceInfo.GetLanguageString());	
	}

	public void Dispose()
	{		
		messageHandler = null;
		if (debugMode)
			TDStockLog.i(LOG_TAG, "We have no reference anymore");	
	}
	
	private ITradeLogoutResponse	responseHandler;

	/** If we are running a demo version, the iUseDemoData could be a fake send **/
	public void SendRequest(boolean iUseDemoData,
			ITradeLogoutResponse iTradingLogoutResponse)
	{
		demoData = iUseDemoData;
		responseHandler = iTradingLogoutResponse;
		messageHandler = new Handler()
		{
			@Override
			public void handleMessage(Message msg)
			{
				if (responseHandler == null)
					return;

				switch (msg.what)
				{
					case REQUEST_DATA_SENT_FAIL:
						responseHandler.ResponseFunc(false);
						break;

					case REQUEST_DATA_SENT_SUCCESS:
						responseHandler.ResponseFunc(true);
						break;
				}
			}
		};
		// Start the Thread
		Thread internalThread = new Thread()
		{
			// On purpose pass in to a message handler, so the thread can sleep or be
			// killed
			@Override
			public void run()
			{
				Message msg;
				
				// Provide success or fail reply
				msg = new Message();
				if (SendData(demoData))
					msg.what = REQUEST_DATA_SENT_SUCCESS;
				else 
					msg.what = REQUEST_DATA_SENT_FAIL;	
				
				if (debugMode)
					TDStockLog.i(LOG_TAG, "Done sending Data");				
				//Flush all information
				TradeAppInfo.ResetAllInfo();
				messageHandler.sendMessage(msg);
			}
		};
		internalThread.setName(LOG_TAG);
		internalThread.start();
	}

	private final int	REQUEST_DATA_SENT_FAIL		= 0;
	private final int	REQUEST_DATA_SENT_SUCCESS	= 1;
	
	// iProcess is for real sending or just a reply
	// This is the decoder part
	private boolean SendData(boolean iUseDemoData)
	{
		//Prevent for multiple call for network
		synchronized(TradeAppInfo.padLock)
		{		
			SoapSerializationEnvelope envelope;

			if (iUseDemoData == true)
			{
				try
				{
					Thread.sleep(Trade_AppConstant.demoHoldTime);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
					TDStockLog.d(LOG_TAG, "SendData=>Exception: " + e.toString());
				}
				if (debugMode)
					TDStockLog.i(LOG_TAG, "Using Prepared Data");				
				return true;
			}
	
			if (DeviceInfo.IsNetworkAvailable(callerContext) == false)
				return false;
	
			envelope = new SoapSerializationEnvelope(TradeAppInfo.SOAP_VERSION);	
			// Set packet ID
			soapRequest.addProperty("SeqNo", TradeAppInfo.GetSeqNo(true));
			// Last modification of the time
			soapRequest.addProperty("Timestamp",
					TradeAppInfo.GetCurrentTimeStamp() + "," + 
					TradeAppInfo.GetSessionToken() + ",logout");
			envelope.setOutputSoapObject(soapRequest);
						
			/* Interestingly, we do not care about the result */
			try
			{				
				SoapTransport dataTransfer;
				String        urlString;			
				
				urlString = TradeAppInfo.GetURLAddress(TradeAppInfo.useSSLSetting);
				if (debugMode)
					TDStockLog.i(LOG_TAG, "URL: " + urlString);
				
				if (TradeAppInfo.useSSLSetting)
					dataTransfer = new SoapTransport( callerContext, urlString, 
						   				    		TradeAppInfo.SOAP_COMMUNIC_Timeout, R.raw.ca_stock);
				else
					dataTransfer = new SoapTransport( callerContext, urlString, 
										   		TradeAppInfo.SOAP_COMMUNIC_Timeout);
							
				if (debugMode)
					TDStockLog.i(LOG_TAG, "Try sending Data");
				
				dataTransfer.SendData(TradeAppInfo.SOAP_SERVICENAME, envelope);				
			}
			catch (java.net.SocketTimeoutException exTimeout)
			{
				exTimeout.printStackTrace();
				TDStockLog.e(LOG_TAG, "Timeout: " + exTimeout.toString());
				return false;
			}
			catch (Exception e)
			{
				e.printStackTrace();
				TDStockLog.e(LOG_TAG, e.toString());
				return false;
			}
					
			return true;
		}
	}
}